#ifndef SPRINGSOLVER_H_
#define SPRINGSOLVER_H_

#include "ModelSolver.h"

#include "InvertMatrix.h"

using namespace boost::numeric::ublas;

namespace common {
/**
 * Solver based on Spring System
 * Lagrange'a Equation.
 */
class SpringSolver: public common::ModelSolver {

	ublasMatrix* getJacobian(_keyType* pointIdSet,_keyType* constrainIdSet) const;
	ublasMatrix* getMatrixK(_keyType* primitiveSet) const ;

	int constraintSize(_keyType* constrainIdSet) const;
	int primitivesSize(_keyType* primitiveSet) const;
	/**
	 * prepare points order and their position
	 * return map<first: pointId , second: position>
	 */
	std::map<int,int> pointOrder(_keyType* pointIdSet) const;
	/**
	 * Right Hand Solution
	 * Vector of Constraint
	 *  return -Q
	 */
	ublasVector rhsQ(_keyType* constrainIdSet);

	/**
	 * Update points after completed calculations
	 */
	void updatePoints(ublasVectorRange& dq,std::map<int,int>& pointOrders);

	/**
	 * Get vector for all primitives F = -K*q
	 */
	ublasVector getForceAll(_keyType* primitiveSet) const;

public:
	SpringSolver();
	void solve();
	void relax();

	virtual ~SpringSolver();
};

}

#endif /* SPRINGSOLVER_H_ */
